#pragma once

#include "TypeTracker.h"
#include <set>

struct ObjectCreationSnapshot
{
	ObjectID objectId;
	ClassID classId;
	CLRClass clrClass;
	std::vector<std::wstring> stack;
};

class ObjectTracker
{
public:
	ObjectTracker(TypeTracker &typeTracker) : m_TypeTracker(typeTracker){}
	~ObjectTracker(void);
	void SetTypeFilter(const std::vector<std::wstring> &typeFilters);

	void Initialize(CComPtr<ICorProfilerInfo2> pCorProfilerInfo);
	STDMETHODIMP ObjectAllocated(ObjectID objectId, ClassID classId);
	STDMETHODIMP SurvivingReferences(ULONG cSurvivingObjectIDRanges,
		ObjectID objectIDRangeStart[  ],
		ULONG cObjectIDRangeLength[  ]);

	STDMETHODIMP MovedReferences( ULONG cMovedObjectIDRanges,
		ObjectID oldObjectIDRangeStart[  ],
		ObjectID newObjectIDRangeStart[  ],
		ULONG cObjectIDRangeLength[  ]);

	HRESULT GetCreationSnapshot(ObjectID objectId, ObjectCreationSnapshot *creationSnapshot) const;

private:
	static void HandleClassLoad(const CLRClass &classLoad, void *data);
	bool PassesFilter(const std::wstring &typeName);

	CComPtr<ICorProfilerInfo2> m_pCorProfilerInfo;
	TypeTracker &m_TypeTracker;

	typedef std::map<ObjectID, ObjectCreationSnapshot>::const_iterator OBJECT_CREATIONS_ITERATOR;
	std::map<ObjectID, ObjectCreationSnapshot> m_resolvedObjectCreations;
	
	typedef std::map<ClassID, ObjectCreationSnapshot>::const_iterator UNRESOLVED_OBJECT_CREATIONS_ITERATOR;
	std::map<ClassID, ObjectCreationSnapshot> m_unResolvedObjectCreations;
	
	std::vector<std::string>::const_iterator TYPE_FILTER_ITERATOR;
	std::set<std::wstring> m_TypeFilters;
};
